﻿#pragma once

#include <string>
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"

#ifdef _WIN32
#include <Windows.h>  // 需包含 Windows 头文件
#endif

// 日志输出目标类型
enum LoggerSinkType {
    LOGGER_CONSOLE,       // 控制台输出
    LOGGER_FILE_BASIC,    // 基本文件输出(不轮转)
    LOGGER_FILE_ROTATING  // 轮转文件输出
};

// 日志级别
enum LogType {
    LOG_TRACE,    // 最详细的跟踪信息
    LOG_DEBUG,    // 调试信息
    LOG_INFO,     // 普通信息
    LOG_WARN,     // 警告信息
    LOG_ERROR,    // 错误信息
    LOG_CRITICAL  // 严重错误信息
};

// 单例日志类
class CampusLogger {
public:
    // 获取单例实例(线程安全)
    static CampusLogger* Instance();

    // 禁止拷贝构造和赋值
    CampusLogger(const CampusLogger&) = delete;
    CampusLogger& operator=(const CampusLogger&) = delete;

    // 设置日志级别
    void setLogLevel(LogType level);

    // 设置日志格式
    void setPattern(const std::string& pattern);

    // 设置默认日志器
    bool setDefaultLogger(LoggerSinkType logger_type,
        const std::string& file_path = "logs/campus.log",
        size_t max_file_size = 1024 * 1024 * 5,  // 5MB
        size_t max_files = 3);                  // 最多3个文件

    // 日志输出方法(支持格式化)
    template<typename... Args>
    void log(LogType type, const char* fmt, const Args&... args) {
        if (!default_logger_) return;

        switch (type) {
        case LOG_TRACE:
            default_logger_->trace(fmt, args...);
            break;
        case LOG_DEBUG:
            default_logger_->debug(fmt, args...);
            break;
        case LOG_INFO:
            default_logger_->info(fmt, args...);
            break;
        case LOG_WARN:
            default_logger_->warn(fmt, args...);
            break;
        case LOG_ERROR:
            default_logger_->error(fmt, args...);
            break;
        case LOG_CRITICAL:
            default_logger_->critical(fmt, args...);
            break;
        default:
            break;
        }
    }

    // 快捷日志输出方法
    template<typename... Args>
    static void trace(const char* fmt, const Args&... args) {
        Instance()->log(LOG_TRACE, fmt, args...);
    }

    template<typename... Args>
    static void debug(const char* fmt, const Args&... args) {
        Instance()->log(LOG_DEBUG, fmt, args...);
    }

    template<typename... Args>
    static void info(const char* fmt, const Args&... args) {
        Instance()->log(LOG_INFO, fmt, args...);
    }

    template<typename... Args>
    static void warn(const char* fmt, const Args&... args) {
        Instance()->log(LOG_WARN, fmt, args...);
    }

    template<typename... Args>
    static void error(const char* fmt, const Args&... args) {
        Instance()->log(LOG_ERROR, fmt, args...);
    }

    template<typename... Args>
    static void critical(const char* fmt, const Args&... args) {
        Instance()->log(LOG_CRITICAL, fmt, args...);
    }

private:
    // 私有构造函数和析构函数
    CampusLogger();
    ~CampusLogger();

    // 单例实例
    static CampusLogger* instance_;
    // 默认日志器
    std::shared_ptr<spdlog::logger> default_logger_;

    // 将自定义日志级别转换为spdlog级别
    spdlog::level::level_enum convertToSpdLevel(LogType level);
};
